local MAJOR, MINOR = "LibMinimapButton-1.0", 1
local lib, oldminor = LibStub:NewLibrary(MAJOR, MINOR)

if not lib then return end -- No upgrade needed

local buttonScripts,buttonMethods
local MINIMAP_RADIUS = 80
local MINIMAP_CORNER_ROUNDING = 10

function lib:NewButton(name) -- naming the button is optional!
	local b = CreateFrame("Button",name,Minimap)
	
	b:SetWidth(31) b:SetHeight(31)
	b:SetFrameStrata("LOW")
	b:SetToplevel(true)
	b:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")

	local icon = b:CreateTexture(nil,"BACKGROUND")
	b.icon = icon
	icon:SetWidth(20) icon:SetHeight(20)
	icon:SetPoint("TOPLEFT",b,"TOPLEFT",7,-5)
	  
	local overlay = b:CreateTexture("OVERLAY")
	overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
	overlay:SetWidth(53) overlay:SetHeight(53)
	overlay:SetPoint("TOPLEFT",b,"TOPLEFT")

	b:RegisterForClicks("LeftButtonUp","RightButtonUp")
	b:RegisterForDrag("LeftButton")
	
	for name,method in pairs(buttonMethods) do
		b[name] = method
	end
	
	for name,script in pairs(buttonScripts) do
		b:SetScript(name,script)
	end
	
	b:SetIcon()
	return b
end

local QUAD1,QUAD2,QUAD3,QUAD4 = 2,3,5,7 -- These can be any 4 unique prime numbers. I just picked the smallest 4.
local quads = {QUAD1,QUAD4,QUAD2,QUAD3} -- quandrants reordered for magic later
local minimapShapes = {
	["ROUND"]					= QUAD1*QUAD2*QUAD3*QUAD4,
	["SQUARE"]					= 1,
	["CORNER-TOPLEFT"]			= QUAD2,
	["CORNER-TOPRIGHT"]			= QUAD1,
	["CORNER-BOTTOMLEFT"]		= QUAD3,
	["CORNER-BOTTOMRIGHT"]		= QUAD4,
	["SIDE-LEFT"]				= QUAD2*QUAD3,
	["SIDE-RIGHT"]				= QUAD1*QUAD4,
	["SIDE-TOP"]				= QUAD1*QUAD2,
	["SIDE-BOTTOM"]				= QUAD3*QUAD4,
	["TRICORNER-TOPLEFT"]		= QUAD1*QUAD3*QUAD4,
	["TRICORNER-TOPRIGHT"]		= QUAD2*QUAD3*QUAD4,
	["TRICORNER-BOTTOMLEFT"]	= QUAD1*QUAD2*QUAD4,
	["TRICORNER-BOTTOMRIGHT"]	= QUAD1*QUAD2*QUAD3,
}

local function updateButtonPosition(button,angle,israd,rounding,radius)
	radius = radius or MINIMAP_RADIUS
	rounding = rounding or MINIMAP_CORNER_ROUNDING
	angle = israd and angle or math.rad(angle)
	button.angle = angle
	
	local x,y = math.cos(angle),math.sin(angle)
	-- Quandrant ordering magic
	local q = x > 0 and 1 or 3
	if y < 0 then q = q + 1 end
	local quad = quads[q]
	
	local shape = GetMinimapShape and GetMinimapShape() or "ROUND"
	local round = math.fmod(minimapShapes[shape],quad) == 0
	
	if round then
		x = x * radius
		y = y * radius
	else
		-- Taken with permission from MobileMinimapButtons.  Thanks go to KarlKFI.
		local diagRadius = math.sqrt(2*(radius)^2)-rounding
		x = math.max(-radius, math.min(x*diagRadius, radius))
		y = math.max(-radius, math.min(y*diagRadius, radius))
	end
	button:SetPoint("CENTER",x,y)
end

buttonMethods = {
	SetIcon = function(self,texture)
		self.icon:SetTexture(texture or "Interface\\Icons\\INV_Misc_QuestionMark")
		self.icon:SetTexCoord(0.075,0.925,0.075,0.925)
	end,

	SetLeftClick = function(self,func,arg)
		self.leftClick = func
		self.leftArg = arg   
	end,

	SetRightClick = function(self,func,arg)
		self.rightClick = func
		self.rightArg = arg   
	end,

	SetTooltip = function(self,title,text)
		self.tooltipTitle = title
		self.tooltipText = text   
	end,
	
	SetPosition = function(self,angle,israd)
		updateButtonPosition(self,angle,israd,self.radius,self.rounding)		
	end,
	
	SetRadius = function(self,radius)
		self.radius = radius
	end,
	
	GetRadius = function(self)
		return self.radius
	end,
	
	GetPosition = function(self)
		return math.deg(self.angle)
	end,
	
}

local OnUpdate = function(self)
	local x,y = GetCursorPosition()
	local mx,my = Minimap:GetCenter()
	local ms = Minimap:GetEffectiveScale()
	self:SetPosition(math.atan2(y/ms-my,x/ms-mx),true)
end

buttonScripts = {
	OnClick = function(self,button)
		if button == "LeftButton" and self.leftClick then
			self.leftClick(self.leftArg)
		elseif button == "RightButton" and self.rightClick then
			self.rightClick(self.rightArg)
		end
	end,
	
	OnMouseDown = function(self)
		--self.icon:SetTexCoord(.1,.9,.1,.9)
		self.icon:SetTexCoord(0,1,0,1)
	end,
	
	OnMouseUp = function(self)
		--self.icon:SetTexCoord(0,1,0,1)
		self.icon:SetTexCoord(0.075,0.925,0.075,0.925)
	end,
	
	OnDragStart = function(self)
		self:SetScript("OnUpdate",OnUpdate)
		self:LockHighlight()
	end,
	
	OnDragStop = function(self)
		self:SetScript("OnUpdate",nil)
		self:UnlockHighlight()
	end,
	
	OnHide = function(self)
		self:SetScript("OnUpdate",nil)
		self:UnlockHighlight()
	end,
	
	OnEnter = function(self)
		if not self.tooltipTitle then return end
		local t = GameTooltip
		t:SetOwner(self,"ANCHOR_BOTTOMLEFT")
		t:SetText(self.tooltipTitle)
		t:AddLine(self.tooltipText)
		t:Show()
	end,
	
	OnLeave = function(self)
		if GameTooltip:IsOwned(self) then
			GameTooltip:Hide()
		end
	end,
}